﻿#include<ctype.h>
#include<time.h>
#include"unrealircd.h"
#include<openssl/hmac.h>
#include<openssl/sha.h>

int is_digist_string(char *str,int length){
    int point_num=0;
    for(int i=0;i<length;i++){
        if(i==0&&(str[i]=='-'||str[i]=='+')){
            continue;
        }
        else if(str[i]=='.'&&point_num==0){
            point_num++;
        }
        else if(!isdigit(str[i])){
            return 0;
        }
    }
    return 1;
}


int is_empty_string(char *str,int length){
    for(int i=0;i<length;i++){
        if(!isspace(str[i])){
            return 0;
        }
    }
    return 1;
}

/**
 * 十六进制转换成十进制
 */
int hex2dec(char c)
{
    if ('0' <= c && c <= '9') 
    {
        return c - '0';
    } 
    else if ('a' <= c && c <= 'f')
    {
        return c - 'a' + 10;
    } 
    else if ('A' <= c && c <= 'F')
    {
        return c - 'A' + 10;
    } 
    else 
    {
        return -1;
    }
}

/**
 * url解码
 */
char* urldecode(const char *url,int length) {
    char *dest=safe_alloc(sizeof(char)*length+1);
    int dest_length=0;
    for(int i=0;i<length;++i){
        if(url[i]!='%'){
            dest[dest_length++]=url[i];
        }
        else{
            char c1 = url[++i];
            char c0 = url[++i];
            int num = 0;
            num = hex2dec(c1) * 16 + hex2dec(c0);
            dest[dest_length++]=num;
        }
    }
    dest[dest_length]='\0';
    char *result=NULL;
    safe_strdup(result,dest);
    safe_free(dest);
    return result;
}

/**
 * int转化成字符串
 */
char *int_to_string(const int i){
    char i_string[30];
    sprintf(i_string,"%d",i);
    char *temp=NULL;
    safe_strdup(temp,i_string);
    return temp;
}

/**
 * int64转化成字符串
 */
char *int64_to_string(const int64_t i){
    char i_string[30];
    sprintf(i_string,"%lld",i);
    char *temp=NULL;
    safe_strdup(temp,i_string);
    return temp;
}

/**
 * 随机一个n位的数字随机数
 */
char *random_digist(int n) {
    
    char * digist=safe_alloc(n+1);
    for(int i=0;i<n;i++){
        digist[i]='0'+(rand()%10);
    }
    digist[n]='\0';
    return digist;
}

/**
 * 获得当前时间的时间戳字符串
 */
char * getCurrectTimeStamp(){
    char temp[20];
    sprintf(temp,"%lld000",time(NULL));
    char *timestamp=NULL;
    safe_strdup(timestamp,temp);
    return timestamp;
}

/**
 * 获得%Y-%m-%d的时间格式
 */
char * getYearMonthDayTimeChar(int64_t timestamp){
    char *dest = safe_alloc(20);
    struct tm sttime;
    sttime = *gmtime(&timestamp);
    strftime(dest, sizeof(char)*20, "%Y-%m-%d", &sttime);
    return dest;

}

char * sha256Hex(const char* str){
    char buf[3];
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    int len=strlen(str);
    SHA256_Update(&sha256, str, len);
    SHA256_Final(hash, &sha256);
    char *newStr=safe_alloc(SHA256_DIGEST_LENGTH*2+10);
    for(int i=0;i<SHA256_DIGEST_LENGTH;i++){
        snprintf(buf,sizeof(buf),"%02x",hash[i]);
        newStr[i*2]=buf[0];
        newStr[i*2+1]=buf[1];
    }
    newStr[SHA256_DIGEST_LENGTH*2]='\0';
    return newStr;

}


char * hmacSha256(const char * key,int keyLength,const char * input,int inputLength,int *resultLength){
    unsigned char hash[32];

    HMAC_CTX *h;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    h = &hmac;
#else
    h = HMAC_CTX_new();
#endif
    
    HMAC_Init_ex(h, key, keyLength, EVP_sha256(), NULL);
    HMAC_Update(h, ( unsigned char* )input, inputLength);
    unsigned int len = 32;
    HMAC_Final(h, hash, &len);

#if OPENSSL_VERSION_NUMBER < 0x10100000L
    HMAC_CTX_cleanup(h);
#else
    HMAC_CTX_free(h);
#endif
    ircd_log(LOG_ERROR,"len:%d",len);
    char *result=safe_alloc(len+1);
    for(int i = 0 ; i < len ; i++){
        result[i] = hash[i];
    };
    result[len] = '\0';
    *resultLength=len;
    return result;
}



char * HexEncode(const char * input,int inputLength){
    static const char* const lut = "0123456789abcdef";
    char * output=safe_alloc(2*inputLength+1);
    for(size_t i = 0 ; i < inputLength ; i++){
        const unsigned char c = input[i];
        output[i * 2] = lut[c >> 4];
        output[i * 2 + 1] = lut[c & 15];
    }
    output[inputLength*2]='\0';
    return output;

}
